package com.ruyuan.eshop.order.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruyuan.eshop.common.enums.OrderStatusEnum;
import com.ruyuan.eshop.common.page.PagingInfo;
import com.ruyuan.eshop.common.utils.ParamCheckUtil;
import com.ruyuan.eshop.order.builder.OrderDetailBuilder;
import com.ruyuan.eshop.order.dao.*;
import com.ruyuan.eshop.order.domain.dto.OrderDetailDTO;
import com.ruyuan.eshop.order.domain.dto.OrderListDTO;
import com.ruyuan.eshop.order.domain.dto.OrderListQueryDTO;
import com.ruyuan.eshop.order.domain.entity.*;
import com.ruyuan.eshop.order.domain.query.OrderQuery;
import com.ruyuan.eshop.order.enums.BusinessIdentifierEnum;
import com.ruyuan.eshop.order.enums.OrderTypeEnum;
import com.ruyuan.eshop.order.exception.OrderErrorCodeEnum;
import com.ruyuan.eshop.order.service.OrderQueryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;

/**
 * @author lxg
 * @Description:
 * @date 2022/4/721:18
 */
@Service
@Slf4j
public class OrderQueryServiceImpl implements OrderQueryService {
    @Autowired
    private OrderInfoDAO orderInfoDAO;

    @Autowired
    private OrderItemDAO orderItemDAO;

    @Autowired
    private OrderAmountDetailDAO orderAmountDetailDAO;

    @Autowired
    private OrderDeliveryDetailDAO orderDeliveryDetailDAO;

    @Autowired
    private OrderPaymentDetailDAO orderPaymentDetailDAO;

    @Autowired
    private OrderSnapshotDAO orderSnapshotDAO;
    @Autowired
    private OrderAmountDAO orderAmountDAO;

    @Autowired
    private OrderOperateLogDAO orderOperateLogDAO;

/*    @Autowired
    private AfterSaleQueryService afterSaleQueryService;*/
    @Override
    public void checkQueryParam(OrderQuery query) {
        ParamCheckUtil.checkObjectNonNull(query.getBusinessIdentifier(), OrderErrorCodeEnum.BUSINESS_IDENTIFIER_IS_NULL);
        checkIntAllowableValues(query.getBusinessIdentifier(), BusinessIdentifierEnum.allowableValues(),"businessIdentifier");
        checkIntSetAllowableValues(query.getOrderTypes(), OrderTypeEnum.allowableValues(),"orderTypes");
        checkIntSetAllowableValues(query.getOrderStatus(), OrderStatusEnum.allowableValues(),"orderStatus");
        Integer maxSize = OrderQuery.MAX_PAGE_SIZE;
        checkSetMaxSize(query.getOrderIds(),maxSize,"orderIds");
        checkSetMaxSize(query.getSellerIds(),maxSize,"sellerIds");
        checkSetMaxSize(query.getParentOrderIds(),maxSize,"parentOrderIds");
        checkSetMaxSize(query.getReceiverNames(),maxSize,"receiverNames");
        checkSetMaxSize(query.getReceiverPhones(),maxSize,"receiverPhones");
        checkSetMaxSize(query.getTradeNos(),maxSize,"tradeNos");
        checkSetMaxSize(query.getUserIds(),maxSize,"userIds");
        checkSetMaxSize(query.getSkuCodes(),maxSize,"skuCodes");
        checkSetMaxSize(query.getProductNames(),maxSize,"productNames");
    }

    private void checkIntAllowableValues(Integer i, Set<Integer> allowableValues, String paramName) {
        OrderErrorCodeEnum orderErrorCodeEnum = OrderErrorCodeEnum.ENUM_PARAM_MUST_BE_IN_ALLOWABLE_VALUE;
        ParamCheckUtil.checkIntAllowableValues(i
                , allowableValues,
                orderErrorCodeEnum,paramName,allowableValues);
    }
    private void checkSetMaxSize(Set setParam,Integer maxSize,String paramName) {
        OrderErrorCodeEnum orderErrorCodeEnum = OrderErrorCodeEnum.COLLECTION_PARAM_CANNOT_BEYOND_MAX_SIZE;
        ParamCheckUtil.checkSetMaxSize(setParam, maxSize,
                orderErrorCodeEnum,paramName
                ,maxSize);

    }

    private void checkIntSetAllowableValues(Set<Integer> set, Set<Integer> allowableValues, String paramName) {
        OrderErrorCodeEnum orderErrorCodeEnum = OrderErrorCodeEnum.ENUM_PARAM_MUST_BE_IN_ALLOWABLE_VALUE;
        ParamCheckUtil.checkIntSetAllowableValues(set
                , allowableValues,
                orderErrorCodeEnum,paramName,allowableValues);
    }

    @Override
    public PagingInfo<OrderListDTO> executeListQuery(OrderQuery query) {
        OrderListQueryDTO queryDTO=OrderListQueryDTO.Builder.builder()
                .copy(query)
                //不展示无效订单
                .removeInValidStatus()
                .setPage(query)
                .build();
        Page<OrderListDTO> orderListDTOPage = orderInfoDAO.listByPage(queryDTO);

        return PagingInfo.toResponse(orderListDTOPage.getRecords(),orderListDTOPage.getTotal(),(int)orderListDTOPage.getCurrent(),(int)orderListDTOPage.getSize());
    }

    @Override
    public OrderDetailDTO orderDetail(String orderId) {
        //1、查询订单
        OrderInfoDO orderInfo=orderInfoDAO.getByOrderId(orderId);
        if (orderInfo==null){
            return null;
        }
        //2、查询订单条目
        List<OrderItemDO> orderItemDOList = orderItemDAO.listByOrderId(orderId);

        //3、查询订单费用明细
        List<OrderAmountDetailDO> orderAmountDetailDOS = orderAmountDetailDAO.listByOrderId(orderId);

        //4、查询订单支付信息
        List<OrderPaymentDetailDO> orderPaymentDetailDOS = orderPaymentDetailDAO.listByOrderId(orderId);

        //5、查询订单配送信息
        OrderDeliveryDetailDO deliveryDetailDO = orderDeliveryDetailDAO.getByOrderId(orderId);
        //6、查询订单费用类型
        List<OrderAmountDO> orderAmountDOS = orderAmountDAO.listByOrderId(orderId);
        //7、查询订单操作日志
        List<OrderOperateLogDO> orderOperateLogDOS = orderOperateLogDAO.listByOrderId(orderId);
        //8、查询订单快照信息
        List<OrderSnapshotDO> orderSnapshotDOS = orderSnapshotDAO.listByOrderId(orderId);
        /*//9、查询缺品退款信息
        List<OrderLackItemDTO> lackItems = null;
        if(isLack(orderInfo)) {
            lackItems = afterSaleQueryService.getOrderLackItemInfo(orderId);
        }*/
        //10、构造返参
        return new OrderDetailBuilder()
                .orderInfo(orderInfo)
                .orderItems(orderItemDOList)
                .orderAmountDetails(orderAmountDetailDOS)
                .orderDeliveryDetail(deliveryDetailDO)
                .orderPaymentDetails(orderPaymentDetailDOS)
                .orderAmounts(orderAmountDOS)
                .orderOperateLogs(orderOperateLogDOS)
                .orderSnapshots(orderSnapshotDOS)
                //.lackItems(lackItems)
                .build();
    }
}
